<?php
/*
 * description：
 * author：wh
 * email：
 * createTime：{2020/6/22} {9:49} 
 */

namespace wanghua\general_utility_tools_php\huawei\obs\service;


class ObjectManage extends BaseObs
{
    /**
     * desc：列举对象, 简单列举
     * 最多返回1000个对象
     * 该接口可设置的参数如下：
     * Prefix
     * 限定返回的对象名必须带有Prefix前缀。
     * Marker
     * 列举对象的起始位置，返回的对象列表将是对象名按照字典序排序后该参数以后的所有对象。
     * MaxKeys
     * 列举对象的最大数目，取值范围为1~1000，当超出范围时，按照默认的1000进行处理。
     * Delimiter
     * 用于对对象名进行分组的字符。对于对象名中包含Delimiter的对象，其对象名（如果请求中指定了Prefix，
     * 则此处的对象名需要去掉Prefix）中从首字符至第一个Delimiter之间的字符串将作为一个分组并作为CommonPrefix返回。
     *
     * 说明：
     * 每次至多返回1000个对象，如果指定桶包含的对象数量大于1000，则返回结果中IsTruncated为true表明本次没有返回全部对象，
     * 并可通过NextMarker获取下次列举的起始位置。
     * 如果想获取指定桶包含的所有对象，可以采用分页列举的方式。
     * author：wh
     * @return array
     */
    function listObjects(){
        $resp = $this->obsClient->listObjects ( [
            'Bucket' => $this->bucketName
        ] );

        $data = [];
        $data['RequestId'] = $resp ['RequestId'];
        $tmp = [];
        foreach ( $resp ['Contents'] as $index => $content ) {
            array_push($tmp, [
                'Key'=>$content ['Key'],
                'LastModified'=> $content ['LastModified'],
                'ETag'=> $content ['ETag'],
                'Size'=> $content ['Size'],
                'OwnerID'=> $content ['Owner']['ID'],
                'OwnerName'=> $content ['Owner']['DisplayName'],
                'StorageClass'=> $content ['StorageClass'],
            ]);
        }
        $data['Contents'] = $tmp;
        return $data;
    }

    /**
     * desc：指定数目列举
     * author：wh
     * @param int $rowsLimit
     * @return array
     */
    function listObjectsLimit (int $rowsLimit=100){
        $resp = $this->obsClient->listObjects ( [
            'Bucket' => $this->bucketName,
            // 列举100个对象
            'MaxKeys' => $rowsLimit
        ] );

        $data['RequestId'] = $resp ['RequestId'];
        $tmp = [];
        foreach ( $resp ['Contents'] as $index => $content ) {
            array_push($tmp, [
                'Key'=>$content ['Key'],
                'LastModified'=> $content ['LastModified'],
                'ETag'=> $content ['ETag'],
                'Size'=> $content ['Size'],
                'OwnerID'=> $content ['Owner']['ID'],
                'OwnerName'=> $content ['Owner']['DisplayName'],
                'StorageClass'=> $content ['StorageClass'],
            ]);
        }
        $data['Contents'] = $tmp;
        return $data;
    }

    /**
     * desc：指定起始位置列举
     * 模糊匹配
     * author：wh
     * @param string $Marker 对象名
     * @param int $MaxKeys 返回数量
     * @return array
     */
    function listObjectsFromStart(string $Marker, int $MaxKeys=100){
        $resp = $this->obsClient->listObjects ( [
            'Bucket' => $this->bucketName,
            // 设置列举对象名字典序在"test"之后的100个对象
            'MaxKeys' => $MaxKeys,
            'Marker' => $Marker
        ] );

        $data = [];
        $data['RequestId'] = $resp ['RequestId'];
        $tmp = [];
        foreach ( $resp ['Contents'] as $index => $content ) {
            array_push($tmp, [
                'Key'=>$content ['Key'],
                'LastModified'=> $content ['LastModified'],
                'ETag'=> $content ['ETag'],
                'Size'=> $content ['Size'],
                'OwnerID'=> $content ['Owner']['ID'],
                'OwnerName'=> $content ['Owner']['DisplayName'],
                'StorageClass'=> $content ['StorageClass'],
            ]);
        }
        $data['Contents'] = $tmp;
        return $data;
    }

    /**
     * desc：列举文件夹中的所有对象
     * author：wh
     */
    function listObjectsForDirAll(string $dir, $MaxKeys=1000){
        $marker = null;
        $index = 1;
        $data = [];
        do {
            $resp = $this->obsClient->listObjects ( [
                'Bucket' => $this->bucketName,
                'MaxKeys' => $MaxKeys,
                // 设置文件夹对象名"dir/"为前缀
                'Prefix' => $dir,
                'Marker' => $marker
            ] );

            $items = [];
            foreach ( $resp ['Contents'] as $content ) {
                $item = [
                    'Key'=>$content ['Key'],
                    'LastModified'=>$content ['LastModified'],
                    'ETag'=>$content ['ETag'],
                    'Size'=>$content ['Size'],
                    'KeyID'=>$content ['Owner'] ['ID'],
                    'OwnerName'=> $content ['Owner']['DisplayName'],
                    'StorageClass'=>$content ['StorageClass'],
                ];
                $items[] = $item;
            }
            $marker = $resp['NextMarker'];
            $data[] = $items;
        }while($resp['IsTruncated']);
        return $data;
    }

    /**
     * desc：获取对象属性
     * 包括对象长度，对象MIME类型，对象自定义元数据等信息。
     * author：wh
     * @param $objectname
     * @return array
     */
    function getObjectMetadata(string $objectname){
        $resp = $this->obsClient -> getObjectMetadata([
            'Bucket' => $this->bucketName,
            'Key' => $objectname
        ]);

        return [
            'RequestId'=>$resp['RequestId'],
            'ContentType'=>$resp['ContentType'],
            'ContentLength'=>$resp['ContentLength'],
            'Metadata'=>$resp['Metadata'],
        ];
    }

    /**
     * desc：删除单个对象
     * 说明：
     * 请您谨慎使用删除操作，若对象所在的桶未开启多版本控制功能，该对象一旦删除将无法恢复。
     * author：wh
     * @param string $objectname
     * @return array
     */
    function deleteObject(string $objectname){

        $resp = $this->obsClient->deleteObject ( [
            'Bucket' => $this->bucketName,
            'Key' => $objectname
        ] );
        return [
            'RequestId'=>$resp['RequestId'],
        ];
    }

    /**
     * desc：获取对象访问权限
     * 对象访问权限与桶访问权限类似，也可支持预定义访问策略（参见桶访问权限）或直接设置。
     * 对象访问权限（ACL）可以通过三种方式设置：
     * 上传对象时指定预定义访问策略。
     * 调用ObsClient->setObjectAcl指定预定义访问策略。
     * 调用ObsClient->setObjectAcl直接设置。
     * 资料参考：https://support.huaweicloud.com/sdk-php-devg-obs/obs_28_0602.html
     * author：wh
     * @param string $objectname
     * @return array
     */
    function getObjectAcl(string $objectname){
        $resp = $this->obsClient->getObjectAcl ( [
            'Bucket' => $this->bucketName,
            'Key' => $objectname
        ] );

        $data = [
            'RequestId'=>$resp['RequestId'],
            'OwnerID'=>$resp ['Owner'] ['ID'],
        ];
        $tmp = [];
        foreach ( $resp ['Grants'] as $index => $grant ) {
            $tmp[] = [
                'GranteeID'=>$grant ['Grantee'] ['ID'],
                'GranteeURI'=>$grant ['Grantee'] ['URI'],
                'Permission'=>$grant['Permission'],
            ];
        }
        $data['Grants'] = $tmp;
        return $data;
    }
}